package com.itkf.core.configCenter.example;

import com.itkf.core.config.DtpProperties;
import com.itkf.core.configCenter.ConfigCenterService;
import com.itkf.core.configCenter.ConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import com.itkf.core.config.ConfigCenter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@ConditionalOnProperty(prefix = "spring.dynamic.tp", name = "config-type", havingValue = "redis")
public class RedisConfigCenterService implements ConfigCenterService {

    private final DtpProperties dtpProperties;
    private RedisTemplate<String, String> redisTemplate;
    private RedisMessageListenerContainer listenerContainer;

    public RedisConfigCenterService(DtpProperties dtpProperties) {
        this.dtpProperties = dtpProperties;
    }

    @Override
    public void init() {
        ConfigCenter.Redis redisConfig = dtpProperties.getConfigCenter().getRedis();

        // 配置连接工厂
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(redisConfig.getHost());
        config.setPort(redisConfig.getPort());
        config.setPassword(RedisPassword.of(redisConfig.getPassword()));

        LettuceConnectionFactory factory = new LettuceConnectionFactory(config);
        factory.afterPropertiesSet();

        // 创建 RedisTemplate
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(RedisSerializer.string());
        template.setValueSerializer(RedisSerializer.string());
        template.afterPropertiesSet();
        this.redisTemplate = template;
    }

    @Override
    public void subscribe(ConfigChangeListener listener) {
        ConfigCenter.Redis redisConfig = dtpProperties.getConfigCenter().getRedis();
        String channel = redisConfig.getChannel();

        // 初始化监听容器
        this.listenerContainer = new RedisMessageListenerContainer();
        listenerContainer.setConnectionFactory(redisTemplate.getConnectionFactory());
        listenerContainer.addMessageListener((message, pattern) -> {
            String newConfig = new String(message.getBody());
            listener.onChange(newConfig);
        }, new ChannelTopic(channel));
        listenerContainer.start();
    }

    @Override
    public void close() {
        if (listenerContainer != null) {
            listenerContainer.stop();
        }
    }
}
